package com.lixh.sdk.base.promision

import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import androidx.activity.ComponentActivity
import androidx.activity.result.*
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle.Event
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import java.util.concurrent.atomic.AtomicInteger

/**
 * 适用于界面创建成功，后动态创建launcher使用
 */

/****************************************************************************************************************/


val mNextLocalRequestCode: AtomicInteger = AtomicInteger()

fun <I, O> ActivityResultCaller.register(
    key: String,
    contract: ActivityResultContract<I, O>,
    callback: ActivityResultCallback<O>
): ActivityResultLauncher<I>? {
    return when (this) {
        is ComponentActivity -> this.register(key, contract, callback)
        is Fragment -> this.register(key, contract, callback)
        else -> null
    }
}


fun <I, O> ComponentActivity.register(
    key: String,
    contract: ActivityResultContract<I, O>,
    callback: ActivityResultCallback<O>
): ActivityResultLauncher<I> {
    return activityResultRegistry.register(key, contract, callback).also {
        lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Event) {
                if (event == Event.ON_DESTROY) {
                    it.unregister()
                }
            }
        })
    }
}


fun <I, O> Fragment.register(
    key: String,
    contract: ActivityResultContract<I, O>,
    callback: ActivityResultCallback<O>
): ActivityResultLauncher<I>? {
    return getActivityResultRegistry()?.register(key, contract, callback).also {
        lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Event) {
                if (event == Event.ON_DESTROY) {
                    it?.unregister()
                }
            }
        })
    }
}


internal fun ActivityResultCaller.startActivityResultLauncher(
    key: String = "startActivityResult",
    callback: ActivityResultCallback<ActivityResult>
): ActivityResultLauncher<Intent>? {
    return register(key, ActivityResultContracts.StartActivityForResult(), callback)
}

internal fun ActivityResultCaller.startRequestPermissionsLauncher(
    key: String = "startRequestMultiplePermissions",
    callback: ActivityResultCallback<Map<String, Boolean>>
): ActivityResultLauncher<Array<String>>? {
    return register(key, ActivityResultContracts.RequestMultiplePermissions(), callback)
}

fun ActivityResultCaller.startRequestPermissionLauncher(
    key: String = "startRequestPermission",
    callback: ActivityResultCallback<Boolean>
): ActivityResultLauncher<String>? {
    return register(key, ActivityResultContracts.RequestPermission(), callback)
}

fun <I, O> ActivityResultCaller.startRequestPermissionByContract(
    key: String = "startRequestPermissionByContract",
    contract: ActivityResultContract<I, O>,
    callback: ActivityResultCallback<O>
): ActivityResultLauncher<I>? {
    return register(key, contract, callback)
}

//endregion
/********************************************Fragment 部分********************************************************/
//region Fragment部分
internal fun Fragment.getActivityResultRegistry(): ActivityResultRegistry? {
    return kotlin.runCatching { requireActivity().activityResultRegistry }
        .onFailure { it.printStackTrace() }
        .getOrNull()
}


/**
 * startActivityResult
 */
fun ActivityResultCaller.startActivityResult(
    key: String = "startActivityResult" + mNextLocalRequestCode.getAndIncrement(),
    intent: Intent,
    callback: ActivityResultCallback<ActivityResult>
) {
    startActivityResultLauncher(key, callback)?.launch(intent)
}

fun ActivityResultCaller.checkSelfPermission(permission: String): Boolean {
    if (ContextCompat.checkSelfPermission(
            context,
            permission
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        return true
    }
    return false
}

internal fun ActivityResultCaller.shouldShowRequestPermissionRationale(permission: String) =
    when (this) {
        is Activity -> ActivityCompat.shouldShowRequestPermissionRationale(this, permission)
        is Fragment -> ActivityCompat.shouldShowRequestPermissionRationale(
            requireActivity(),
            permission
        )
        else -> false
    }

val ActivityResultCaller.context
    get() = when (this) {
        is Activity -> this
        is Fragment -> this.requireContext()
        else -> throw IllegalArgumentException("The constructor's ActivityResultCaller argument must be Activity or Fragment.")
    }